package com.example.curator;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 *  zookeeper  CRUD 操作
 *      事务操作
 */
@SpringBootApplication
public class CuratorApplication {

    public static void main(String[] args) {
        SpringApplication.run(CuratorApplication.class, args);

        // curatorFramework 两种创建方式
//        CuratorFramework framework = CuratorFrameworkFactory.newClient("192.168.232.130:2181",
//                5000, 5000,
//                new ExponentialBackoffRetry(1000, 3));

        //使用Fluent风格api创建
        CuratorFramework framework = CuratorFrameworkFactory.builder()
                .connectString("192.168.232.130:2181,192.168.232.130:2182,192.168.232.130:2183")
                .sessionTimeoutMs(5000)// 会话超时时间
                .connectionTimeoutMs(5000)// 连接超时时间
                .namespace("gupao") // 隔离名称
                .retryPolicy(new ExponentialBackoffRetry(1000, 3)) // 重试策略
                .build();

        framework.start();

        // CRUD
        // framework.create()
        // framework.delete()
        // framework.setData()
        // framework.getData()

//        createData(framework, "/myzoo/nodeA", "one");
//        updateData(framework, "/myzoo/nodeA", "update1");
        delData(framework, "/myzoo/nodeA");

    }

    public static void createData(CuratorFramework framework, String key, String value){

        if(null == value) value = "";

        try {
            framework.create().creatingParentsIfNeeded() // 递归创建所需父节点
                    .withMode(CreateMode.PERSISTENT) // 创建类型为持久节点
                    .forPath(key, value.getBytes()); // 目录及内容
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static String getData(CuratorFramework framework, String key){

        try {
            String value = new String(framework.getData().forPath(key));
            return value;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void updateData(CuratorFramework framework, String key, String value){

        try {
            framework.setData().forPath(key, value.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除节点， 验证version
     * @param frameWork
     * @param key
     */
    public static void delData(CuratorFramework frameWork, String key){

        Stat stat = new Stat();
        try {
            String value = new String(frameWork.getData().storingStatIn(stat).forPath(key));
            System.out.println(value);
            frameWork.delete().withVersion(stat.getVersion()).forPath(key);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 事务操作
     */
    public static void transaction(CuratorFramework framework){
        try {

            framework.inTransaction().check().forPath("/nodeA")
                    .and()
                    .create().withMode(CreateMode.EPHEMERAL).forPath("/nodeB", "init".getBytes())
                    .and()
                    .create().withMode(CreateMode.EPHEMERAL).forPath("/nodeC", "init".getBytes())
                    .and()
                    .commit();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
